{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "7a5c2153",
   "metadata": {},
   "source": [
    "[![Open in Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/langchain-ai/langchain-academy/blob/main/module-4/research-assistant.ipynb) [![Open in LangChain Academy](https://cdn.prod.website-files.com/65b8cd72835ceeacd4449a53/66e9eba12c7b7688aa3dbb5e_LCA-badge-green.svg)](https://academy.langchain.com/courses/take/intro-to-langgraph/lessons/58239974-lesson-4-research-assistant)"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "id": "e0a5763f-5f45-4b8f-b3e2-480f46c5721b",
   "metadata": {},
   "source": [
    "# Research Assistant\n",
    "\n",
    "## Review\n",
    "\n",
    "We've covered a few major LangGraph themes:\n",
    "\n",
    "* Memory\n",
    "* Human-in-the-loop\n",
    "* Controllability\n",
    "\n",
    "Now, we'll bring these ideas together to tackle one of AI's most popular applications: research automation. \n",
    "\n",
    "Research is often laborious work offloaded to analysts. AI has considerable potential to assist with this.\n",
    "\n",
    "However, research demands customization: raw LLM outputs are often poorly suited for real-world decision-making workflows. \n",
    "\n",
    "Customized, AI-based [research and report generation](https://jxnl.co/writing/2024/06/05/predictions-for-the-future-of-rag/#reports-over-rag) workflows are a promising way to address this.\n",
    "\n",
    "## Goal\n",
    "\n",
    "Our goal is to build a lightweight, multi-agent system around chat models that customizes the research process.\n",
    "\n",
    "`Source Selection` \n",
    "* Users can choose any set of input sources for their research.\n",
    "  \n",
    "`Planning` \n",
    "* Users provide a topic, and the system generates a team of AI analysts, each focusing on one sub-topic.\n",
    "* `Human-in-the-loop` will be used to refine these sub-topics before research begins.\n",
    "  \n",
    "`LLM Utilization`\n",
    "* Each analyst will conduct in-depth interviews with an expert AI using the selected sources.\n",
    "* The interview will be a multi-turn conversation to extract detailed insights as shown in the [STORM](https://arxiv.org/abs/2402.14207) paper.\n",
    "* These interviews will be captured in a using `sub-graphs` with their internal state. \n",
    "   \n",
    "`Research Process`\n",
    "* Experts will gather information to answer analyst questions in `parallel`.\n",
    "* And all interviews will be conducted simultaneously through `map-reduce`.\n",
    "\n",
    "`Output Format` \n",
    "* The gathered insights from each interview will be synthesized into a final report.\n",
    "* We'll use customizable prompts for the report, allowing for a flexible output format. \n",
    "\n",
    "![Screenshot 2024-08-26 at 7.26.33 PM.png](https://cdn.prod.website-files.com/65b8cd72835ceeacd4449a53/66dbb164d61c93d48e604091_research-assistant1.png)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "f23991e9-51b3-4e9f-86a0-dec16aa7d1e6",
   "metadata": {
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "%%capture --no-stderr\n",
    "%pip install --quiet -U langgraph langchain_openai langchain_community langchain_core tavily-python wikipedia"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "99a1c01d-87e1-4723-b83e-ebcf937fe914",
   "metadata": {},
   "source": [
    "## Setup"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "ba917800-10e4-4e2a-8e9e-30893b731e97",
   "metadata": {},
   "outputs": [],
   "source": [
    "import os, getpass\n",
    "\n",
    "def _set_env(var: str):\n",
    "    if not os.environ.get(var):\n",
    "        os.environ[var] = getpass.getpass(f\"{var}: \")\n",
    "\n",
    "_set_env(\"OPENAI_API_KEY\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "afe9ff57-0826-4669-b88b-4d0501a509f5",
   "metadata": {},
   "outputs": [],
   "source": [
    "from langchain_openai import ChatOpenAI\n",
    "llm = ChatOpenAI(model=\"gpt-4o\", temperature=0) "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3419257b-2c6b-4d68-ae38-4a266cc02982",
   "metadata": {},
   "source": [
    "We'll use [LangSmith](https://docs.smith.langchain.com/) for [tracing](https://docs.smith.langchain.com/concepts/tracing)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "5102cf2e-0ca9-465b-9499-67abb8132e5d",
   "metadata": {},
   "outputs": [],
   "source": [
    "_set_env(\"LANGSMITH_API_KEY\")\n",
    "os.environ[\"LANGSMITH_TRACING\"] = \"true\"\n",
    "os.environ[\"LANGSMITH_PROJECT\"] = \"langchain-academy\""
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f8fe5d93-e353-44bb-be3e-434654bcb7ea",
   "metadata": {},
   "source": [
    "## Generate Analysts: Human-In-The-Loop\n",
    "\n",
    "Create analysts and review them using human-in-the-loop."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "1eee8e60-e548-49b1-88ec-a4f3aef2174e",
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "from typing_extensions import TypedDict\n",
    "from pydantic import BaseModel, Field\n",
    "\n",
    "class Analyst(BaseModel):\n",
    "    affiliation: str = Field(\n",
    "        description=\"Primary affiliation of the analyst.\",\n",
    "    )\n",
    "    name: str = Field(\n",
    "        description=\"Name of the analyst.\"\n",
    "    )\n",
    "    role: str = Field(\n",
    "        description=\"Role of the analyst in the context of the topic.\",\n",
    "    )\n",
    "    description: str = Field(\n",
    "        description=\"Description of the analyst focus, concerns, and motives.\",\n",
    "    )\n",
    "    @property\n",
    "    def persona(self) -> str:\n",
    "        return f\"Name: {self.name}\\nRole: {self.role}\\nAffiliation: {self.affiliation}\\nDescription: {self.description}\\n\"\n",
    "\n",
    "class Perspectives(BaseModel):\n",
    "    analysts: List[Analyst] = Field(\n",
    "        description=\"Comprehensive list of analysts with their roles and affiliations.\",\n",
    "    )\n",
    "\n",
    "class GenerateAnalystsState(TypedDict):\n",
    "    topic: str # Research topic\n",
    "    max_analysts: int # Number of analysts\n",
    "    human_analyst_feedback: str # Human feedback\n",
    "    analysts: List[Analyst] # Analyst asking questions"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "fd088ff5-4c75-412c-85f0-04afd0900bfc",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/jpeg": "/9j/4AAQSkZJRgABAQAAAQABAAD/4gHYSUNDX1BST0ZJTEUAAQEAAAHIAAAAAAQwAABtbnRyUkdCIFhZWiAH4AABAAEAAAAAAABhY3NwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAA9tYAAQAAAADTLQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAlkZXNjAAAA8AAAACRyWFlaAAABFAAAABRnWFlaAAABKAAAABRiWFlaAAABPAAAABR3dHB0AAABUAAAABRyVFJDAAABZAAAAChnVFJDAAABZAAAAChiVFJDAAABZAAAAChjcHJ0AAABjAAAADxtbHVjAAAAAAAAAAEAAAAMZW5VUwAAAAgAAAAcAHMAUgBHAEJYWVogAAAAAAAAb6IAADj1AAADkFhZWiAAAAAAAABimQAAt4UAABjaWFlaIAAAAAAAACSgAAAPhAAAts9YWVogAAAAAAAA9tYAAQAAAADTLXBhcmEAAAAAAAQAAAACZmYAAPKnAAANWQAAE9AAAApbAAAAAAAAAABtbHVjAAAAAAAAAAEAAAAMZW5VUwAAACAAAAAcAEcAbwBvAGcAbABlACAASQBuAGMALgAgADIAMAAxADb/2wBDAAMCAgMCAgMDAwMEAwMEBQgFBQQEBQoHBwYIDAoMDAsKCwsNDhIQDQ4RDgsLEBYQERMUFRUVDA8XGBYUGBIUFRT/2wBDAQMEBAUEBQkFBQkUDQsNFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBT/wAARCAFUAJsDASIAAhEBAxEB/8QAHQABAAICAwEBAAAAAAAAAAAAAAUGBwgCAwQBCf/EAFQQAAEDAwICAgwICgcGBgMAAAECAwQABQYREgchEzEIFBUWIkFRVZTR0tMXNlRWYXSTlSMyQlNxdYGSsrM3UnJ2kaHBCSQzNWKCJSY0lrG0g8PU/8QAGwEBAQADAQEBAAAAAAAAAAAAAAECAwQFBgf/xAA0EQACAAMEBggGAwEAAAAAAAAAAQIDERIhUZEEEzFSYaEFFDNBQnGB0RUjU7HB8CIysuH/2gAMAwEAAhEDEQA/AP1TpSlAKUpQCuDzzcdsuOrS22nrUs6AftqGvF2lOTk2m1JSZ6kdI7JcTuaiNk6BShqNyjodqfHoSdAOfma4e2ZxxL9zj935o65V2AfVr5UpI2N/oQlI+it6ghSrMdPv+/tC0xJE5RZknQ3eAD5DJR66d9Vl88QPSUeunerZQAO48DQcv/So9VO9Wy+Z4HoyPVV+Tx5FuHfVZfPED0lHrp31WXzxA9JR66d6tl8zwPRkeqnerZfM8D0ZHqp8njyFw76rL54geko9dO+qy+eIHpKPXTvVsvmeB6Mj1U71bL5ngejI9VPk8eQuHfVZfPED0lHrr0RLxAuCtsWbGkq8jLqVn/I15+9Wy+Z4HoyPVXnl4Njs5BS/Y7evUabhGQFDnryUBqOfkp8njyFxOUqrOxpmGIVJjvSbnZU6qfiPKL0iMn+uyr8ZaR1ltWqtNdh1SEKszLzcllt5lxLrTiQtDiCClQPMEEdYrXHBZvTqiUOdKUrWQUpSgFKUoBXwkAankK+1wdbDra0K/FUCk6eQ0BW+HmkzHGrysAyL0ruitfPUpcALSef9VoNp/wC2rPVb4cKUnBbJHcBD0OMmE8Cnbo6z+CXy8XhIVVkrfP7WLzZXtFQGb53YeHFgcvWR3BFttyHEM9IULcUtxaglCEIQCpaiToEpBJ8lT9Y24/2mz3jh/wBHebRkN1Zamx5DC8VZU7cYT6F7m5LQT4WrahryCv7J6q0EK9m/ZTYzi0bBJsNmfdbZk9zdg9sM2yYVx0NIcLiuiSwVlYWgI6MgK5qUAQhWllzLsgsD4fPwmcgvL1tclxETkBdulLDbCyQlx4paIZGqVD8Jt00OumhrC0iVxCuOCcN8qyaxXy9u41mjslaW7Zsusi19DJYZkuxG+Yc/CoKkJSDpz29dc+MsnJ88v19iS7TnysdueNNd7drsDD0Vp6W8h0PpuK0lJbUklodG8pLe3dyJ1oDNuVcd8Hwy9xrPc7ys3STCTco8ODBkTHH46lKSHG0str3jVKtdupAGp0HOoXh72Qdqz3idmGGogz4kuxzu02Xl2+V0cgJZQ44tbimQ21opSkpSpWqwkKTqFCqFwHxq7scSsJudwsVygoi8LLfanpE6E410MpEj8KwpSkjRY26lPWRoeog1ZeH8i4YZx94kWy449ejGye5RblbrxHgrdgFtMBptYcfSNrSgtlSdqtCdydNQaAzhSlKAVV8M0t0q+WROgYt8oGMkfksOoS4lP6EqLiQOoJSn9AtFVjGR21lGVTk69F2wzDSSNNxaaBUR5QFOKT+lJrol3wRp4LOq/DZVsZZ6UpXOQUpSgFKUoBSlKArEpC8Ruku4ttKds81YdmIbSVLjO7QnpgkdaCEjcBzBG7nqojhkuBYZxUiW+RfbFZsqjMBS4bs2M3KQgL03FskEAK2p1069o8lWqq7NwO1yJTkqMZVplOHc47bZK4+8nrKkJOxR+lSSa6LUEz+9zx9/30Lt2laHY38KQ2pA4cYuEKIUU9yWNCRrodNv0n/E1NYjwkwnALg7PxrErLYJrrRYckW6C2w4tskKKCpIBI1Sk6fQK7ThMjxZTfgPJ0zP+rVO8mR86r99sz7qmrl7/JiixLRSqv3kyPnVfvtmfdViXjnesh4dZDwvhWrKLqpnJMnYs83thTSiGFoWSUaNjRWqRzOv6KauXv8AJiixNgq8d4s8DIbXKttzhsXC3ymy0/Fkthxt1B60qSeRB8hqD7yZHzqv32zPuqd5Mj51X77Zn3VNXL3+TFFiV49jVwmI0+DbFvuhj2a9Nt7H3hjZrjFuEDh/jcOdEdQ/HksWtlDjTiSFJWlQTqCCAQR1EVMd5Mj51X77Zn3VO8Nt4FMy+Xuc0RoW1zlNBQ+nogg/58+o8qWJa2x8n/wUWJ6rxkCy+u1WctybyoaEqBU1DBH/ABHiOr6EahSzyGg3KTIWWzsWG2MQY24tt6krcOq3FqJUtaj41KUSonxkmudrtMKyxBFgRWoccEq6NlASCo9ajp1k9ZJ5nx166wiiVLEGz7gUpStRBSlKAUpSgFKUoBSlKAUpSgFa79lh8cuAv9/In8tytiK137LD45cBf7+RP5blAbEUpSgFKUoBSlKAUpSgFKUoBSlKAUpSgFKUoBSlKAVrv2WHxy4C/wB/In8tytiK137LD45cBf7+RP5blAbEUpSgFKUoBSlKAUpSgFKUoBSleK83ePYrc7Nk7y2jRIQ2nctalEJShI8aiogAeU1UnE6LaD20qlKyHLXjvbtVojoPMNvTnFLA/wCopa01+gaj6TXHu7mHyCx+lve7rr6rHis0Whd6VSO7uYfILH6W97und3MPkFj9Le93TqseKzQoXelUju7mHyCx+lve7p3dzD5BY/S3vd06rHis0KF3r8Nuyh4Kv8BeM99xjo1i1lfbdrdXz6WI4SW+fjKdCgn+shVfsl3dzD5BY/S3vd1h3jv2Pb3H+/4ddr/As7b+PTA8pDch1SZsfUKVGc1b/FKkpOvWAVgfjah1WPFZoUHYAcDfge4GxJ86P0OQ5PsuczcnRbbRT/u7R6j4KFFWh5hTqh4q2ZqkC+ZgBoLfYwPrb3u6d3cw+QWP0t73dOqx4rNChd6VSO7uYfILH6W97und3MPkFj9Le93TqseKzQoXelUju7mHyCx+lve7p3dzD5BY/S3vd06rHis0KF3pVI7u5h8gsfpb3u6lLHlEmRcE227Q2oM5xCnGFR3i6y+lJG4BRSkpWNQSkjqOoKtFbcYtHjhVbn5NChY6UpXKQVUeJJ/8MtI8Ru0TUf8A5BVuqo8Sv+W2j9bRP5grq0XtofMq2nrpVI428QXeFXCnJsrjxkTJVtiFxhl06IU6ohCN2n5O5QJ+gGse5+jiRwq4O5rk87iGq93WJZHX2WhZ4rLUWUACFtaJ1UgeENrm/XUEnlpW9uhDPNK114gZnxAwKDh1jZvc/IcnzGUsl6BboW63tsxi68iI04ptCiTpoX1rISFHwiAD1NcQOIGP4LkqMvm3nHHO3ocXHrzJtEGRdJ63iQuOmJHdWyp3VJSlXgjRYJT4JqWgbGuOJaQpa1BCEglSlHQAeU1yB1Go6q00zfNcwy7seuOePZLOuTE/HG2iiVPhRI8yRHdYQ70T7bJW0PyhubIJSR+KdayLxJzHNcFk4Pglmu17yK9XtuZNkXmNAtypyGGA34DTThZj66upG5QJCUnwVE6haBsNSsbcELtnNwtF3Yzi3y4zsWZst8y4NRmZMuMUJO51uO642laVladUkAgJOgOorv445W5imGNLi36XYblOmswoS7dbUT5cl5RJDLLK/BK1BKuavBSASeQq1uqDIVK1RZ41cQo/DXLY8mc9DyixZXa7SzPu1ujpfXHlOxTpIYZWprdteUCW1DVJBBSrmLfK4g33hzkXELHsozgvwrfjsa+Qshl2xkvQlOuvMFBZZShLw3toKU6bju2knUGpaQM8Tp0a2QpEyZIaiRI7annpD6whtpCRqpSlHkAACSTyAFcoktifFZlRXm5MZ5CXGnmlBSHEEahSSORBBBBFaox+IuZTrHxXxLKXbxNjd40m8wZOQWyLAmJCkPNLSW4yikoOiSNwSsEKBHUau1n4hTeGw4Wv3e4BrBrviojOJW2gJiTmIyZCXCvTd+EZQ8naTpq0nQAk6rQM+1xDiC4WwpO8AKKdeYB6jp+w/wCFaoSeJPE2HZsPyDJ8nmYhit4tzlykXmJZGJjcF96QVx40tOwlplEdTSek0BK925Yq34hY7tL7K3iLPi5XNRDatlnfVBQxGUzKbWJYQ0pZaKwhJBUFIUFHedSRoAtVBsFULczpmGH6eOa+D+jtR8/6CsRdj3m2UXq+3C055kcpGYsxlPysUmWlqKiMnpdofiPIH4djqTu3LOpGpB5Vly6fHDDvrz//ANN+t0t1r5RfZlRfqUpXkkFVHiV/y20fraJ/MFW6oTMLI9fbOG4xQJcd9qUwHDohS21hW0nQ6BQBTrodNddDpXRo8Shmwt7KlW0hclxu25hj9xsd4ionWu4MLjSY69QFoUNCNRzH6RzHWKxqOxxgPYrescuGZ5heLTcrau1Bi4XFt0RmVFPNv8ENVjaAFubyBqNeZq/Ky1LB2SbNfY7w5KbFqee2nyb2krQf0pUR9NfO/ON5sv33JL91XfqY34S2WRnEDhVZ+I1mtsGe9OgybW+iVb7pbX+hlw3kgpC216EalJIIIKSDzFQ83gXAuuIpslyybJblKauTd3jXuVOQqdFkoACFtHow2kAAjYEbfCVqNSatffnG82X77kl+6p35xvNl++5JfuqaiPdYsvApts7HjHYcPMo0243q+t5dFRFvCrpLDqnylCkB0EISUL2qCdE6JAQjRI0rql9jxbLjYbPDmZVlEq7WWSuTa8jXNbFyhbm0tqbQ4loJLakp0KVoVu1OutXfvzjebL99yS/dU7843my/fckv3VNRHusWXgQDdnyrh/Zoduxtk5spTjrsqdlV/WxICiQU6FEZwEc1eCAgJ0GgOvKNvGF37ixDYiZha2MSctktq42u6Y3fVSpTElIUncOkiISBsWoEELBCiCPHVx7843my/fckv3VRtg4sY/lcAzbKbjd4YcWyZEG1yXmwtJ0UnclsjUHkR4jTUTN1kssqrHY1Y83EvbDt6yCYbzcLfdZr0uWh1xyVEcStDmpb5b9iEqSPB2oAQEVNZnwPx3PbxfrhdlzluXmzsWZ9pp4IQ22y+t9txshO5Lgcc111I8FPLr1kLPxYx7InJ7dqVcLm5b5KocxMO2SXTGfT+M04EoOxY8aToR5Kku/ON5sv33JL91TUR7rLZeBTbR2Ptmg32deLjfcgySfcLS7ZJzl4mIcEmIsg7ClDaQjb4WhbCfx1E7idaqPE7gPKyLhvi3CmDEmXrGmpTDkrIbxcGy9BjMvBXRJASFuKU0Vso0AASfCV5cwd+cbzZfvuSX7qnfnG82X77kl+6qaiPdYsvArfEjgtB4mjteZkWQ2q0uRO0JVotMxLMSWxqSUOIKFEaglJKCk7eWtdk3gza151Byq23W8Y/OYisQn41rkIRGnMMqKmm3kLQrUJ3KGqSk6KI1qwd+cbzZfvuSX7qnfnG82X77kl+6q6iPdYsvArOD8ErfhWUnIncgyHJrqiEq3Rn7/NTIMWOpaVqQjahOuqkI1UvcrwRzq1XT44Yd9ef/8Apv119+cbzZfvuSX7qvXaIkrIsgt9xXDkQYFtLi2zLbLbjzqkFvkgjVKQlSuZ0JJGg5GqoHKTcSoqPmmgk1tLvSlK8cxFKUoBSlKAUpSgFKUoCn8Yc1Tw44VZdk5UErtVrkSmtfynUtno0/tXtH7ao/Y12OPwf7FnEhcSWEQrKbvPUv8AGSpwKku7j5QVqH7Kr/ZuPLvfDnG8CYWQ/m+S2+yrCDopLHSh11f6AGhr9CqzFxEwlvPOG+SYkiR3Mbu9qkWxMhDZUI4daU2FbApO4J3a7dRrppqNaA/HfgR2VeRcGeNFwzUlc2DfJbj18tiV+DKQ44VqUnU6dIkqJSo+UjqUoH9ksIzWzcRcTtmSY9NRcbNcmQ9HkN6jcNSCCDzCgQUlJ5ggg8xWmtn/ANmBiWNZphkl6a5lWOtsvoySPd5a4pfdLSUsLiJjpSpA6UqJQtw6J0G5R69zMNw2ycPcXtuOY5bWbTZbc0GY0NgHahOupJJ1KlEkqUpRKlKJJJJJoCapSlAKUpQClKUApSlAKUpQClKUApSlAKUpQGuecA5z2bXDyyHVUTDsem5E6n8kuyFCK2D9KdNwrYytds2/8rdnHw3uf4icoxe42MnxKMdaZQH6edbE0BjTsgsfxO64ALvmcmdCs2MTWMhEq3al5p2OSpCgAlRI5nUAdR6x11frNd41/s8G6Ql9LDmsNyWF6abm1pCknT9BFVHjbfbzj/DufIsOJpza5OOsR02Z1O5t5C3UpcKxofBSgqV1HqFXdhhqKw2yy2hlltIQhttISlKQNAAB1ADxUB2UpSgFKUoBSlKAUpSgFKVxW4hsarUEj/qOlAcqV1dtM/nm/wB4U7aZ/PN/vCrRg7aV1dtM/nm/3hTtpn883+8KUYO2ldXbTP55v94U7aZ/PN/vClGD80uyK7Pi033ingdwseFXiLLwi6OSZKL483EkLWQtp+KW0dLsGgT4ZUTrqCjlqdo+wy7I7LeyWtmY3++WS2Waww56IlpRB6RTvUpbiHlqUQtSUKY8JKUAkqO0agDBH+0h7F9m5RV8V8UjIVMZARf4kcAl1vqTKAHjTySv6NquW1ROyvYZYA1wu7G/DbY8G2bhLjd05gOiVdK+ekAUP6yUKQg/2KUYLtxKt19vF6wqNYsrj44tm7onToiyOlucNoHpY6AdTod6SogcuXMVe6xNdpWC5N2R9hhSkS3s4xiyP3SG+lRERmPIX2u4CddC4dBy01289ayp20z+eb/eFKMHbSurtpn883+8KdtM/nm/3hSjB20rq7aZ/PN/vCnbTP55v94UowdtK6u2mfzzf7wr6JDSiAHUEnqAUKUYOylKVAeW6Te5tsly9u7oGVu7fLtST/pWPLXiVqv1uiXK82+JeLlKZQ89JnMJeVqoAlKdw8FA6gkaDQeXU1ecq+LF4+pvfwGq9jXxctX1Rr+AV6WjtwS3FC6OplsR4vg+xb5tWf0Br2afB9i3zas/oDXs1jGP2TmP2HPs4x/L7nEtDdmujEOG41GfVoy5GZc6SQ4kKQ2C44pIWrYnlp1gmspRc1ss2/XuzMTekuVlYYkz2Q0sdC28FlpW7TarcG18kkkac9NRW1T5j8bzJV4nX8H2LfNqz+gNezT4PsW+bVn9Aa9mqrK7Izh9Eh2uSq+uOpuluTdobce3Snnn4iiR0qW0NFeg0OvLVI5kAV34v2QGAZnd7bbbNkKJsm5JUqCsRnkMSilO5aG3lIDa1pGpUgKKk6HUDQ018zfeYq8Sx/B9i3zas/oDXs0+D7Fvm1Z/QGvZqBtPHbBr3mXerEvmt8LzsdDD0R9pDrrWvSNturQG3FJ2q1CVE8j5K857Ibh8L2q0nIAJiLiq0untOR0LMtLha6Fx7o+jbUVjRIUobtQU6gglr5m+8xV4lm+D7Fvm1Z/QGvZp8H2LfNqz+gNezU/WF5PHKZeeyCb4dWLteMzAYbfuUi4Wqa4t9RLhU0ytIS23ohskOuKKVKUEpCiDVc+YvE8xV4mSPg9xXXXvas+v1Br2a+/B9i3zas/oDXs1Xrdx8wK7ZO3YIuQtO3F2QqIyosPJjvvp11abkFAacXqCNqVk6gjSk7j5gVtyhePychabuLclMJxXQPGM3IJADK5AR0SXNSBsKwdTpprU18zfeYq8Sw/B9i3zas/oDXs0+D7Fvm1Z/QGvZrHvHDskcb4U2PJ40e6R38vttscls29cV99pDpQSymQpobWws6aBa0EgjTrFRETspLRYM3yW0ZnMjWiDAh2yTFfjQpLp/wB4YLjqnlIC0oQlW0BStoAPMmp1iNeN5irxMs/B9i3zas/oDXs0+D7Fvm1Z/QGvZqEzPjfhWAN29y9Xromp8cy47kWI/LQtjl+FKmULCUcx4R0HPrr0ZRxhw7DrLabrc74ymHdwFW4xW3JTk1JSFgsttJUtwbSDqkEAEa9dZa+ZvvMVeJJ/B9i3zas/oDXs0HD/ABca6Y3aBqCDpBa6jyP5NUaLx0hXLiLaocSVD7zpWMTr87cpLTjLrao8llo67ynYgBbm4KTrqkcxoQci41kcDL7BAvVrccets5pL8d11hxhS2zzSrY4lKgCOY1A1BB6jUU+Y/E8xV4ndhT64N6vFiS6pyHFZjy46HFFSmUul1JbBPPaFMkganTdoNEhIFwqk4x/SLkX6rt382bV2rj0pUm+i5pB7SLyr4sXj6m9/Aar2NfFy1fVGv4BVhyr4sXj6m9/Aar2NfFy1fVGv4BW6T2L8/wADuMBX/EbxJxXsnmU2Wc67eEv9zUCKsqmnuQ0hPQjT8J+EBSNuvhAjrrjZ3Lzw4zbJpk3FsguyMkxezswl2yAt8dsx2X0OMPKHJlWrqDq4Up6+eo0rZGlSyQ1k7HLEL5Y8q4evXKy3C3tReGrUB9yVEcaSzIEtCiysqA2uaDXYeeg10rx4dhl+h8Hux8iOWK4sTrXlSH5zC4biXYjPRTwVup01bRqtA1VoPCT5RW09KWQabCBmF/v+DXLIbRnc/LLZmDcu8lxh4WeDG6R1pJitJPRuJCXGz0jaVqCekK1DmKsV+wy/Pdj/AMWbe3Yriu4zM3lzYkVMRwvPtG6NOJdbTpqpJSkqCgCNBrroK2npUsAViCJjV0lceuIslDEqFDn4xbokW5llQaLwXM3BC9NCpG9BIB1Go8oqwzOAPDS4S35UrAcckSX1qddedtbKlrWo6qUSU8ySSdaulrtcOx22Lb7fFZgwYraWWI0dAQ20hI0SlKRyAA5aCstu0GqXBXh1bWbdhuH5ZiPERu/2N9nplO3CeuxNPxjvbktqL3QFBUhJSlAJBVptABNePB+FsKDBkcP86xjiNc5rt4fS5Ittwn9xJjDspTqJJKHksIACwpaSArcknaSa3DpWNhA1IzJm+4hiPHnD3sLyS8XTKZNxuFruloti5ceW1IjpS22pxP4i2tpRsVodEjaFa85q1Xm5cOc34gu3DA8nv8a92q0RoaLfaVvsyXGoRQ40tXUgauBJUrRI8Ia6gitnaVbINR4GIZlg1hwbDckZzCXj8LFG2ksYaXPwt1K1BbMh9ogoQhstpTuUlo+ESeWlceF9pyLhgzwnyu84hf7lCt2Jv4zNhQ7et+ba5QkIV0vQDw1IWGinegHltP4qhrt1SpZBqrxa4bXfsi+INjfix7/iVuexO4AruEDo0qfTMYLEeUkhQCFqQl0tk7lIRoQPCA2D4Z5LcMtwm13G72aTj93LZam22SypssvoJQsI3DwmypJKFDUKSUkddWelZJUdQRmMf0i5F+q7d/Nm1dqpOMf0i5F+q7d/Nm1dq1aX2vpD/lFZF5V8WLx9Te/gNVzH95xi29GUhztNraVDUa7BprVjyr4sXj6m9/Aar2NfFy1fVGv4BW2T2L8/wO48iYWR7Ruu1v3ac9Lev3tfe0sh87QPu9XvanKVLPEhB9pZD52gfd6ve07SyHztA+71e9qcpSzxBB9pZD52gfd6ve07SyHztA+71e9qcpSzxBB9pZD52gfd6ve07SyHztA+71e9qcpSzxBB9pZD52gfd6ve07SyHztA+71e9qcpSzxBB9pZD52gfd6ve07SyHztA+71e9qcpSzxBB9pZD52gfd6ve07SyHztA+71e9qcpSzxBB9pZD52gfd6ve1I25qay0oTpLMlzXkplktADyaFSv/AJr10qpUBGYx/SLkX6rt382bV2qk4x/SLkX6rt382bV2rVpfa+kP+UVkXlXxYvH1N7+A1Xsa+Llq+qNfwCrDlXxYvH1N7+A1XceUUYzbFBBcIhtEITpqrwByGug/xrbJ7F+f4HcSdQua5GMPxC9X1Ud2Um2w3ZamWdm5SUIKjpvWhPUCeah1ddQqc9vijz4b5OnkTqZNr/8A7aicuZu/FnD79iD+N33EGbxBdhru00wX22kLTtUNjMtSySkqA5ac+ZpXAhCL7ItmwY829eMevFyucHG4mR3lVmitBiIw8l0qUelfBBT0LhKNVK00279DpLwuMEq4cV7nj7NikHGLbao86Vf1OMIaZW8lxxBWFPBYRsaI5IKtx1ISnRSurKeBwySBxFiovPaScvixYGqIu7tOKy10ZaHhjfu3PHXwdOk6jpz9J4QPuZNnb7t6bXjuXREx5VsELa+wpMZMbVuR0mgRsSTsLZ8JRO7xVP5AjEdk1jYiPzn7TfIdr7jS7/CnSI7SUXCHHSlTjjSOl6ROoWgp6VDYVuGhqVmcbGIEPH3ZGJZI1Lv83tO2W8sx+2X/APd1P9KU9Po2jagpPSFKkq/GSlOqhV7L2MzNr4cXvFDLsEZVzZjxHLlaMbbgvOsIWkuB/a6elW4kFJVqkAnXb1g5JvWE92s+xnJHJuxqyR5jaIXRa9I6+Gkhzfu5bUocTpodek6xpzK0CAm8cbRbLBl10l2u6sDF1x2J0bYyp1T7zLLoYbKXSlS09sNpPhBO48iRzry3DsgLRbLnPZesV97l2+8N2OZe0sMmGxJWptKNT0vSFBU6hO5KCATz0qJu/AK6XOfdo6csZZxu6ZNGyWXbjat0h5TS2FmOp/ptOjJjo00bChoBqoDQwvDfhNkOWWBiTlF0MKxTcgk5I7jirWpiUt3t1b7CJDy3CShJS0rYG0HwUgkjrlYgXzhtxLuud5VmUJ/G5Vus1nuTlvh3NbjBRIU0lAdCgl5S9xWpZHgBISkaqC9UiduvFLC7Fe1Wa5ZdYbfd0qQg2+Vc2WpAUoAoHRqUFakKSRy56jy1H8MMAuPDxq+Q5F7Zu9tmXKTcYiO0Sy+wqQ+686l1zpFB7wnAAQlGgT1HXlIXXhzarxe1XWRLvzcpSkKLcXIZ8ePqkAD8A2+lsDkNRt0PMnUk65X0BBcd8zueE4KzIsheF4m3W326MI7SHXFdLKbS4EpX4JPRdJpr/iOuvG32QVjXFU0q03pvIxc1WcYwWGjcFSg0HikAOFrb0Sg50nSbNp5qB5VMcT+H9yztWNu229sWaTZLkLo12zBMtp51LTjaAtIcbO0dKo6BQOoTzGlY/vvYsRb6iJcZl1gXjJhcZFynTL/ZUToU1bzTbRQYu9OxKEMshvReqdnMq1OsdqtwOeY8dbhkFixOPhtrvDFyyG9yLQ6pCISpMHtXpFSgkOullTmjKwlWq2+RJJO1KrRH43WiHcoVtVFvNxt5uSLAcnLDIhuT93R9Gdq0rJLgKCpDXRheqdRpoPOxg048VMJDNtah47iVnlDtmOw3HjvTHw02lLLKSdoS2h4nloOkSATz08+PcBpFodtVvl5Gmdilmuz16t1qTA6J7thbrjqOnf6Q9KltbqlJCUIJISVFWnOXg9sbsgrG/YrpfXLReotghSn4CLk6w0UTZLcrtZLMdtLhdcU45+IQjaeolJBAs2C8QGc5N2a7k3GyTrXITGlQrn0JdQpTaXEnVlxxGhStJ03ajxgVTLl2PcW6cFLHgUi5tSXrU5HlJnyoCXmZEhtzpFKdjKVotDiivcgq6lfja86vPDzDWcExaPaW2LSwtCluO9xLYm3RVKUonVLAUvby2gkqUTpqTVVa3gkcY/pFyL9V27+bNq7VScY/pFyL9V27+bNq7Vr0vtfSH/KKzy3WF3StcyJu29Oytrd5NySP9ax9Z8ptdnt0W23afFtVziMoZfizHktLCkpAJAUfCSdNQoagjx1kuup+KzJADzSHQOrekHT/ABrGVOUCcMSqhUo3fxjnn+1+mt+1Tv4xzz/a/TW/aq6dyoXyOP8AZJ9VO5UL5HH+yT6q3a+VuvNewuKX38Y55/tfprftU7+Mc8/2v01v2quncqF8jj/ZJ9VO5UL5HH+yT6qa+VuvNewuKX38Y55/tfprftU7+Mc8/wBr9Nb9qrp3KhfI4/2SfVTuVC+Rx/sk+qmvlbrzXsLil9/GOef7X6a37VO/jHPnBa/TW/aq6dyoXyOP9kn1Vi7jTacCN+4bd9LsmBMGRs9xUQW/BkTdqtjbuiT4BGuuug+mmvlbrzXsLid7+Mc8/wBr9Nb9qnfxjnn+1+mt+1V07lQvkcf7JPqp3KhfI4/2SfVTXyt15r2FxS+/jHPP9r9Nb9qnfxjnn+1+mt+1V07lQvkcf7JPqp3KhfI4/wBkn1U18rdea9hcUvv4xzz/AGv01v2qd/GOef7X6a37VXTuVC+Rx/sk+qncqF8jj/ZJ9VNfK3XmvYXFL7+Mc8/2v01v2qHOMcAJOQWsAAknt1vkB1n8arp3KhfI4/2SfVX1NshoUFJiMJUDqCGwCP8AKmvlbrzXsLir4UyqffLxfUIUmFKZjxI61pKS8louqLgB/JKniAdBrtJGqSkm40pXJNma2O1+3XB3ilKVqIKUpQClKUApSlAKx/xTus623jBW4eFoy1Eq+NMvyltb+47ZSrWWDtVtKerXwevrrIFUfiRasouV1w1eOZDFsUWNeG3rszI01nxAlW5hGqT4ROh8XV10BeKUpQClKUApSlAKUpQClKUApSlAKUpQClKUApSlAKxTxui4TJyDhkrLpk2LNayVhdiTEBKXZ+xWxDmiT4Gm7r0/TWVq0VzD/ac8MptwsPQYPebn2pcEuyF3eJHQ7CSAQXY4Di9XgeQBKOs+EKA3qpWIux67JnG+yUg3qbjFqvkCHanGmXH7vHaaQ6tYUdrZQ4vUpCQVa6ab09evLLtAKUpQClKUApSlAKUpQClKUApSlAKV8JCQSSABzJNYey7jLLmPuRcZLTMVJKTdXUBwu/Synq2+RatQeeiSCFHs0bRJulxWZS9e5FMxUrWORfb9LcLj+S3haz1luWWR+63tA/YK6u6V4+cV7+8nvar210FM75i5i42hr8i+z77HqRw749om2KA47aszdMqEyyjXSYpYDzKR5StSVgeR0AdVbp90rx84r395Pe1Ubd7X3wP29+6TZ1yetz4lQnJklbqozw6nGyonYsf1k6Gr8Cj+osmLjMnY2cGo3Abg7YcTbDa5zLfbFxfbHJ6Wvm6rXxgHRCSfyUJrJ9avd0rx84r395Pe1TulePnFe/vJ72qfAo/qLJi42hpWr6bpeUnUZFe9fpuLp/8AlVTNm4jZTYXUqFzN3jjTdFuSQdR49rqQFJP0ncPorXH0HOSrBGnyFxsPSoDDsyg5nbTJi6svtkJkRHCOkYV5Dp1g9YI5Eft0n6+ejgilxOCNUaIKUpWAFKUoBSlKAUpSgMZcccgci2qFYmFFJuhWZJHydAG9H/eVJSfKncKxN1Ve+OLS0ZfZHVf8NyC+hH9pLjZV/kpP+FUSv0LoqCGDRIHD31bzp+BEKUpXrGBFXDLbHaLkxbp15t8K4SNOhiSJTbbrmp0G1BIJ5+QV13PNceskgsXG/WyA+FpbLUqY22oKUNUp0UQdSCCB4xWutwtVndybPbRmuTTbFOul1eLUTuZGfM2GsJDCmXFx3HFbU+DolXgFPIA86trOMwO+TjBGlsIuK49kgxhIloSt1SRDc11Vp1kpBOnjFeYtKjidEltpybvyKZlvWS2jG2GnrvdYVrZdVsbcmyEMpWryAqI1P0VGcOsyHEDD4N+TFEJMpTyQyHelA2Orb13aDXXZr1eOsI4reLNZr/id0zrozAl4bbmrTLnMlxgPFOshA5EBxWrZ8pHL6KyP2N/R/A1YehSEM75WxITt0T207oNPFy8VZytIc2alsVHd3923O4GS6UpXoEJLF8gcxTJ7dckKKWFOojS0+JbK1BJJ/sEhf/aR462UrUu+NLkWmSw0NzzyeibA8a1Han/MittK+Q6dlwqKXGtrqsqU+5n3ClKV8sBSlKAUpSgFKUoCncUMOdy7H09phJukJztiMFEAL5aLbJPVuSSAfEdpPIVgdtwPJWNFtrSotuNrBSttQOikqB5pUDyIPMVtTVPzDhhacufMwqdt1zI07cikAr5aALQdUr05cyNQBoCK+h6N6SWjLVTf69zw/wCDaarfBTavOuTf+5J/vq+q4VWtSiTdcm1J15ZHPH/7qza/wNv7a9GL5bn0eJTsNxs/t0Wqur4Ecl862n7F311760zo9+JZP2FkosZhMWO0ylS1JbQEBTiytRAGmpUSST9J5muyrt8COS+dbT9i766fAjkvnW0/Yu+ut/xHQ/qLn7EslJqv5BhELJJqZUmbeIy0thsIt93lRGyASdShpxKSefXpr1eQVlb4Ecl862n7F310+BHJfOtp+xd9dYxafoUSpFMTz9i2TC/wU2vTTurk3/uSf76pzHsZjYyy81Gk3GSl1QUTcbg/LUNB+SXVqKR9ArJqeCOSE87tagPKGXT/AK1MWbgQ2HkuXy8OT2gde1ITRjNq+hStylkfoKa0vpDQJX8oYlXgnX7CzxK5wxxBzJ8gj3F5BFotrwd3qHJ+Qk+AlPlCFDcT4lJSOfhAZ6rohQo9uiMxYjDcWMykIbZZQEIQkdQAHID6K76+P03S4tMm23clsQFKUrgApSlAKUpQClKUApSlAKUpQClKUApSlAKUpQClKUApSlAKUpQH/9k=",
      "text/plain": [
       "<IPython.core.display.Image object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "from IPython.display import Image, display\n",
    "from langgraph.graph import START, END, StateGraph\n",
    "from langgraph.checkpoint.memory import MemorySaver\n",
    "from langchain_core.messages import AIMessage, HumanMessage, SystemMessage\n",
    "\n",
    "analyst_instructions=\"\"\"You are tasked with creating a set of AI analyst personas. Follow these instructions carefully:\n",
    "\n",
    "1. First, review the research topic:\n",
    "{topic}\n",
    "        \n",
    "2. Examine any editorial feedback that has been optionally provided to guide creation of the analysts: \n",
    "        \n",
    "{human_analyst_feedback}\n",
    "    \n",
    "3. Determine the most interesting themes based upon documents and / or feedback above.\n",
    "                    \n",
    "4. Pick the top {max_analysts} themes.\n",
    "\n",
    "5. Assign one analyst to each theme.\"\"\"\n",
    "\n",
    "def create_analysts(state: GenerateAnalystsState):\n",
    "    \n",
    "    \"\"\" Create analysts \"\"\"\n",
    "    \n",
    "    topic=state['topic']\n",
    "    max_analysts=state['max_analysts']\n",
    "    human_analyst_feedback=state.get('human_analyst_feedback', '')\n",
    "        \n",
    "    # Enforce structured output\n",
    "    structured_llm = llm.with_structured_output(Perspectives)\n",
    "\n",
    "    # System message\n",
    "    system_message = analyst_instructions.format(topic=topic,\n",
    "                                                            human_analyst_feedback=human_analyst_feedback, \n",
    "                                                            max_analysts=max_analysts)\n",
    "\n",
    "    # Generate question \n",
    "    analysts = structured_llm.invoke([SystemMessage(content=system_message)]+[HumanMessage(content=\"Generate the set of analysts.\")])\n",
    "    \n",
    "    # Write the list of analysis to state\n",
    "    return {\"analysts\": analysts.analysts}\n",
    "\n",
    "def human_feedback(state: GenerateAnalystsState):\n",
    "    \"\"\" No-op node that should be interrupted on \"\"\"\n",
    "    pass\n",
    "\n",
    "def should_continue(state: GenerateAnalystsState):\n",
    "    \"\"\" Return the next node to execute \"\"\"\n",
    "\n",
    "    # Check if human feedback\n",
    "    human_analyst_feedback=state.get('human_analyst_feedback', None)\n",
    "    if human_analyst_feedback:\n",
    "        return \"create_analysts\"\n",
    "    \n",
    "    # Otherwise end\n",
    "    return END\n",
    "\n",
    "# Add nodes and edges \n",
    "builder = StateGraph(GenerateAnalystsState)\n",
    "builder.add_node(\"create_analysts\", create_analysts)\n",
    "builder.add_node(\"human_feedback\", human_feedback)\n",
    "builder.add_edge(START, \"create_analysts\")\n",
    "builder.add_edge(\"create_analysts\", \"human_feedback\")\n",
    "builder.add_conditional_edges(\"human_feedback\", should_continue, [\"create_analysts\", END])\n",
    "\n",
    "# Compile\n",
    "memory = MemorySaver()\n",
    "graph = builder.compile(interrupt_before=['human_feedback'], checkpointer=memory)\n",
    "\n",
    "# View\n",
    "display(Image(graph.get_graph(xray=1).draw_mermaid_png()))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "6c22cb05-c436-4358-8f7a-72d722f9b5cc",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Name: Dr. Emily Carter\n",
      "Affiliation: Tech Innovators Inc.\n",
      "Role: Technical Analyst\n",
      "Description: Dr. Carter focuses on the technical benefits and challenges of adopting new frameworks. She is particularly interested in the performance, scalability, and integration capabilities of LangGraph.\n",
      "--------------------------------------------------\n",
      "Name: Michael Thompson\n",
      "Affiliation: Business Insights Group\n",
      "Role: Business Analyst\n",
      "Description: Michael examines the business implications of adopting new technologies. He is concerned with cost-benefit analysis, return on investment, and the potential for LangGraph to provide a competitive edge.\n",
      "--------------------------------------------------\n",
      "Name: Sophia Martinez\n",
      "Affiliation: User Experience Research Lab\n",
      "Role: UX Analyst\n",
      "Description: Sophia is dedicated to understanding how new frameworks impact user experience. She evaluates the usability, learning curve, and overall satisfaction of developers and end-users when using LangGraph.\n",
      "--------------------------------------------------\n"
     ]
    }
   ],
   "source": [
    "# Input\n",
    "max_analysts = 3 \n",
    "topic = \"The benefits of adopting LangGraph as an agent framework\"\n",
    "thread = {\"configurable\": {\"thread_id\": \"1\"}}\n",
    "\n",
    "# Run the graph until the first interruption\n",
    "for event in graph.stream({\"topic\":topic,\"max_analysts\":max_analysts,}, thread, stream_mode=\"values\"):\n",
    "    # Review\n",
    "    analysts = event.get('analysts', '')\n",
    "    if analysts:\n",
    "        for analyst in analysts:\n",
    "            print(f\"Name: {analyst.name}\")\n",
    "            print(f\"Affiliation: {analyst.affiliation}\")\n",
    "            print(f\"Role: {analyst.role}\")\n",
    "            print(f\"Description: {analyst.description}\")\n",
    "            print(\"-\" * 50)  "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "2f81ad23-5656-43e6-b50a-0d7a4f69a60a",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "('human_feedback',)"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Get state and look at next node\n",
    "state = graph.get_state(thread)\n",
    "state.next"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "72b2a402-fd10-4f26-9a32-3e3c0d4aaf76",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'configurable': {'thread_id': '1',\n",
       "  'checkpoint_ns': '',\n",
       "  'checkpoint_id': '1ef6c730-ed11-660c-8002-c9533d30fd7b'}}"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# We now update the state as if we are the human_feedback node\n",
    "graph.update_state(thread, {\"human_analyst_feedback\": \n",
    "                            \"Add in someone from a startup to add an entrepreneur perspective\"}, as_node=\"human_feedback\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "b8816eb9-9906-441b-b552-be71107db14f",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Name: Dr. Emily Carter\n",
      "Affiliation: Tech Innovators Inc.\n",
      "Role: Technical Analyst\n",
      "Description: Dr. Carter focuses on the technical benefits and challenges of adopting new frameworks. She is particularly interested in the performance, scalability, and integration capabilities of LangGraph.\n",
      "--------------------------------------------------\n",
      "Name: Michael Thompson\n",
      "Affiliation: Business Insights Group\n",
      "Role: Business Analyst\n",
      "Description: Michael examines the business implications of adopting new technologies. He is concerned with cost-benefit analysis, return on investment, and the potential for LangGraph to provide a competitive edge.\n",
      "--------------------------------------------------\n",
      "Name: Sophia Martinez\n",
      "Affiliation: User Experience Research Lab\n",
      "Role: UX Analyst\n",
      "Description: Sophia is dedicated to understanding how new frameworks impact user experience. She evaluates the usability, learning curve, and overall satisfaction of developers and end-users when using LangGraph.\n",
      "--------------------------------------------------\n",
      "Name: Dr. Emily Carter\n",
      "Affiliation: Tech Innovators Inc.\n",
      "Role: Technology Analyst\n",
      "Description: Dr. Carter focuses on evaluating emerging technologies and their potential impact on various industries. She is particularly interested in how LangGraph can streamline processes and improve efficiency in tech-driven companies.\n",
      "--------------------------------------------------\n",
      "Name: Michael Thompson\n",
      "Affiliation: Green Ventures\n",
      "Role: Startup Advisor\n",
      "Description: Michael Thompson is an advisor for early-stage startups, helping them navigate the challenges of growth and innovation. He is keen on understanding how LangGraph can provide a competitive edge to startups by enhancing their operational capabilities.\n",
      "--------------------------------------------------\n",
      "Name: Sarah Lee\n",
      "Affiliation: Global Enterprises Ltd.\n",
      "Role: Business Strategist\n",
      "Description: Sarah Lee specializes in developing strategic business plans for large enterprises. She is interested in how LangGraph can be integrated into existing business models to drive scalability and long-term success.\n",
      "--------------------------------------------------\n"
     ]
    }
   ],
   "source": [
    "# Continue the graph execution\n",
    "for event in graph.stream(None, thread, stream_mode=\"values\"):\n",
    "    # Review\n",
    "    analysts = event.get('analysts', '')\n",
    "    if analysts:\n",
    "        for analyst in analysts:\n",
    "            print(f\"Name: {analyst.name}\")\n",
    "            print(f\"Affiliation: {analyst.affiliation}\")\n",
    "            print(f\"Role: {analyst.role}\")\n",
    "            print(f\"Description: {analyst.description}\")\n",
    "            print(\"-\" * 50) "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "a43ac322-5926-4932-8653-68206fec0d2c",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'configurable': {'thread_id': '1',\n",
       "  'checkpoint_ns': '',\n",
       "  'checkpoint_id': '1ef6c731-5ec7-6e04-8004-626a441d897c'}}"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# If we are satisfied, then we simply supply no feedback\n",
    "further_feedack = None\n",
    "graph.update_state(thread, {\"human_analyst_feedback\": \n",
    "                            further_feedack}, as_node=\"human_feedback\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "ab034e65-aeee-4723-8d6d-74541b548425",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Continue the graph execution to end\n",
    "for event in graph.stream(None, thread, stream_mode=\"updates\"):\n",
    "    print(\"--Node--\")\n",
    "    node_name = next(iter(event.keys()))\n",
    "    print(node_name)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "2f204e8a-285c-4e46-8223-a695caec7764",
   "metadata": {},
   "outputs": [],
   "source": [
    "final_state = graph.get_state(thread)\n",
    "analysts = final_state.values.get('analysts')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "59704086-cb3b-42e9-8395-37be6f0d44e9",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "()"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "final_state.next"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "95717ba3-aa00-48d6-bbb7-5fe4db5919bf",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Name: Dr. Emily Carter\n",
      "Affiliation: Tech Innovators Inc.\n",
      "Role: Technology Analyst\n",
      "Description: Dr. Carter focuses on evaluating emerging technologies and their potential impact on various industries. She is particularly interested in how LangGraph can streamline processes and improve efficiency in tech-driven companies.\n",
      "--------------------------------------------------\n",
      "Name: Michael Thompson\n",
      "Affiliation: Green Ventures\n",
      "Role: Startup Advisor\n",
      "Description: Michael Thompson is an advisor for early-stage startups, helping them navigate the challenges of growth and innovation. He is keen on understanding how LangGraph can provide a competitive edge to startups by enhancing their operational capabilities.\n",
      "--------------------------------------------------\n",
      "Name: Sarah Lee\n",
      "Affiliation: Global Enterprises Ltd.\n",
      "Role: Business Strategist\n",
      "Description: Sarah Lee specializes in developing strategic business plans for large enterprises. She is interested in how LangGraph can be integrated into existing business models to drive scalability and long-term success.\n",
      "--------------------------------------------------\n"
     ]
    }
   ],
   "source": [
    "for analyst in analysts:\n",
    "    print(f\"Name: {analyst.name}\")\n",
    "    print(f\"Affiliation: {analyst.affiliation}\")\n",
    "    print(f\"Role: {analyst.role}\")\n",
    "    print(f\"Description: {analyst.description}\")\n",
    "    print(\"-\" * 50) "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7d2498e4-20ae-4503-9dd0-a4165132b7a7",
   "metadata": {},
   "source": [
    "## Conduct Interview\n",
    "\n",
    "### Generate Question\n",
    "\n",
    "The analyst will ask questions to the expert."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "e5d5f559-f42e-442b-87cd-dbf0a91abf9c",
   "metadata": {},
   "outputs": [],
   "source": [
    "import operator\n",
    "from typing import  Annotated\n",
    "from langgraph.graph import MessagesState\n",
    "\n",
    "class InterviewState(MessagesState):\n",
    "    max_num_turns: int # Number turns of conversation\n",
    "    context: Annotated[list, operator.add] # Source docs\n",
    "    analyst: Analyst # Analyst asking questions\n",
    "    interview: str # Interview transcript\n",
    "    sections: list # Final key we duplicate in outer state for Send() API\n",
    "\n",
    "class SearchQuery(BaseModel):\n",
    "    search_query: str = Field(None, description=\"Search query for retrieval.\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "1c2e71eb-07ad-4bea-aabc-dbaf551408c0",
   "metadata": {},
   "outputs": [],
   "source": [
    "question_instructions = \"\"\"You are an analyst tasked with interviewing an expert to learn about a specific topic. \n",
    "\n",
    "Your goal is boil down to interesting and specific insights related to your topic.\n",
    "\n",
    "1. Interesting: Insights that people will find surprising or non-obvious.\n",
    "        \n",
    "2. Specific: Insights that avoid generalities and include specific examples from the expert.\n",
    "\n",
    "Here is your topic of focus and set of goals: {goals}\n",
    "        \n",
    "Begin by introducing yourself using a name that fits your persona, and then ask your question.\n",
    "\n",
    "Continue to ask questions to drill down and refine your understanding of the topic.\n",
    "        \n",
    "When you are satisfied with your understanding, complete the interview with: \"Thank you so much for your help!\"\n",
    "\n",
    "Remember to stay in character throughout your response, reflecting the persona and goals provided to you.\"\"\"\n",
    "\n",
    "def generate_question(state: InterviewState):\n",
    "    \"\"\" Node to generate a question \"\"\"\n",
    "\n",
    "    # Get state\n",
    "    analyst = state[\"analyst\"]\n",
    "    messages = state[\"messages\"]\n",
    "\n",
    "    # Generate question \n",
    "    system_message = question_instructions.format(goals=analyst.persona)\n",
    "    question = llm.invoke([SystemMessage(content=system_message)]+messages)\n",
    "        \n",
    "    # Write messages to state\n",
    "    return {\"messages\": [question]}"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "be2ff33a-6232-4a79-8a82-882a645394f5",
   "metadata": {},
   "source": [
    "### Generate Answer: Parallelization\n",
    "\n",
    "The expert will gather information from multiple sources in parallel to answer questions.\n",
    "\n",
    "For example, we can use:\n",
    "\n",
    "* Specific web sites e.g., via [`WebBaseLoader`](https://python.langchain.com/v0.2/docs/integrations/document_loaders/web_base/)\n",
    "* Indexed documents e.g., via [RAG](https://python.langchain.com/v0.2/docs/tutorials/rag/)\n",
    "* Web search\n",
    "* Wikipedia search\n",
    "\n",
    "You can try different web search tools, like [Tavily](https://tavily.com/)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "id": "606ea95b-e811-4299-8b66-835d4016c338",
   "metadata": {},
   "outputs": [],
   "source": [
    "def _set_env(var: str):\n",
    "    if not os.environ.get(var):\n",
    "        os.environ[var] = getpass.getpass(f\"{var}: \")\n",
    "\n",
    "_set_env(\"TAVILY_API_KEY\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "id": "c61ae74a-f838-4e97-8bd5-48ccd15b7789",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Web search tool\n",
    "from langchain_community.tools.tavily_search import TavilySearchResults\n",
    "tavily_search = TavilySearchResults(max_results=3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "id": "2d8f760b-5a1a-4fa9-a014-d3fb02bec51c",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Wikipedia search tool\n",
    "from langchain_community.document_loaders import WikipediaLoader"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "06cb1603",
   "metadata": {},
   "source": [
    "Now, we create nodes to search the web and wikipedia.\n",
    "\n",
    "We'll also create a node to answer analyst questions.\n",
    "\n",
    "Finally, we'll create nodes to save the full interview and to write a summary (\"section\") of the interview."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "id": "9c863768-2278-415b-aef1-96fd18c1b1cb",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/jpeg": "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",
      "text/plain": [
       "<IPython.core.display.Image object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "from langchain_core.messages import get_buffer_string\n",
    "\n",
    "# Search query writing\n",
    "search_instructions = SystemMessage(content=f\"\"\"You will be given a conversation between an analyst and an expert. \n",
    "\n",
    "Your goal is to generate a well-structured query for use in retrieval and / or web-search related to the conversation.\n",
    "        \n",
    "First, analyze the full conversation.\n",
    "\n",
    "Pay particular attention to the final question posed by the analyst.\n",
    "\n",
    "Convert this final question into a well-structured web search query\"\"\")\n",
    "\n",
    "def search_web(state: InterviewState):\n",
    "    \n",
    "    \"\"\" Retrieve docs from web search \"\"\"\n",
    "\n",
    "    # Search query\n",
    "    structured_llm = llm.with_structured_output(SearchQuery)\n",
    "    search_query = structured_llm.invoke([search_instructions]+state['messages'])\n",
    "    \n",
    "    # Search\n",
    "    search_docs = tavily_search.invoke(search_query.search_query)\n",
    "\n",
    "     # Format\n",
    "    formatted_search_docs = \"\\n\\n---\\n\\n\".join(\n",
    "        [\n",
    "            f'<Document href=\"{doc[\"url\"]}\"/>\\n{doc[\"content\"]}\\n</Document>'\n",
    "            for doc in search_docs\n",
    "        ]\n",
    "    )\n",
    "\n",
    "    return {\"context\": [formatted_search_docs]} \n",
    "\n",
    "def search_wikipedia(state: InterviewState):\n",
    "    \n",
    "    \"\"\" Retrieve docs from wikipedia \"\"\"\n",
    "\n",
    "    # Search query\n",
    "    structured_llm = llm.with_structured_output(SearchQuery)\n",
    "    search_query = structured_llm.invoke([search_instructions]+state['messages'])\n",
    "    \n",
    "    # Search\n",
    "    search_docs = WikipediaLoader(query=search_query.search_query, \n",
    "                                  load_max_docs=2).load()\n",
    "\n",
    "     # Format\n",
    "    formatted_search_docs = \"\\n\\n---\\n\\n\".join(\n",
    "        [\n",
    "            f'<Document source=\"{doc.metadata[\"source\"]}\" page=\"{doc.metadata.get(\"page\", \"\")}\"/>\\n{doc.page_content}\\n</Document>'\n",
    "            for doc in search_docs\n",
    "        ]\n",
    "    )\n",
    "\n",
    "    return {\"context\": [formatted_search_docs]} \n",
    "\n",
    "answer_instructions = \"\"\"You are an expert being interviewed by an analyst.\n",
    "\n",
    "Here is analyst area of focus: {goals}. \n",
    "        \n",
    "You goal is to answer a question posed by the interviewer.\n",
    "\n",
    "To answer question, use this context:\n",
    "        \n",
    "{context}\n",
    "\n",
    "When answering questions, follow these guidelines:\n",
    "        \n",
    "1. Use only the information provided in the context. \n",
    "        \n",
    "2. Do not introduce external information or make assumptions beyond what is explicitly stated in the context.\n",
    "\n",
    "3. The context contain sources at the topic of each individual document.\n",
    "\n",
    "4. Include these sources your answer next to any relevant statements. For example, for source # 1 use [1]. \n",
    "\n",
    "5. List your sources in order at the bottom of your answer. [1] Source 1, [2] Source 2, etc\n",
    "        \n",
    "6. If the source is: <Document source=\"assistant/docs/llama3_1.pdf\" page=\"7\"/>' then just list: \n",
    "        \n",
    "[1] assistant/docs/llama3_1.pdf, page 7 \n",
    "        \n",
    "And skip the addition of the brackets as well as the Document source preamble in your citation.\"\"\"\n",
    "\n",
    "def generate_answer(state: InterviewState):\n",
    "    \n",
    "    \"\"\" Node to answer a question \"\"\"\n",
    "\n",
    "    # Get state\n",
    "    analyst = state[\"analyst\"]\n",
    "    messages = state[\"messages\"]\n",
    "    context = state[\"context\"]\n",
    "\n",
    "    # Answer question\n",
    "    system_message = answer_instructions.format(goals=analyst.persona, context=context)\n",
    "    answer = llm.invoke([SystemMessage(content=system_message)]+messages)\n",
    "            \n",
    "    # Name the message as coming from the expert\n",
    "    answer.name = \"expert\"\n",
    "    \n",
    "    # Append it to state\n",
    "    return {\"messages\": [answer]}\n",
    "\n",
    "def save_interview(state: InterviewState):\n",
    "    \n",
    "    \"\"\" Save interviews \"\"\"\n",
    "\n",
    "    # Get messages\n",
    "    messages = state[\"messages\"]\n",
    "    \n",
    "    # Convert interview to a string\n",
    "    interview = get_buffer_string(messages)\n",
    "    \n",
    "    # Save to interviews key\n",
    "    return {\"interview\": interview}\n",
    "\n",
    "def route_messages(state: InterviewState, \n",
    "                   name: str = \"expert\"):\n",
    "\n",
    "    \"\"\" Route between question and answer \"\"\"\n",
    "    \n",
    "    # Get messages\n",
    "    messages = state[\"messages\"]\n",
    "    max_num_turns = state.get('max_num_turns',2)\n",
    "\n",
    "    # Check the number of expert answers \n",
    "    num_responses = len(\n",
    "        [m for m in messages if isinstance(m, AIMessage) and m.name == name]\n",
    "    )\n",
    "\n",
    "    # End if expert has answered more than the max turns\n",
    "    if num_responses >= max_num_turns:\n",
    "        return 'save_interview'\n",
    "\n",
    "    # This router is run after each question - answer pair \n",
    "    # Get the last question asked to check if it signals the end of discussion\n",
    "    last_question = messages[-2]\n",
    "    \n",
    "    if \"Thank you so much for your help\" in last_question.content:\n",
    "        return 'save_interview'\n",
    "    return \"ask_question\"\n",
    "\n",
    "section_writer_instructions = \"\"\"You are an expert technical writer. \n",
    "            \n",
    "Your task is to create a short, easily digestible section of a report based on a set of source documents.\n",
    "\n",
    "1. Analyze the content of the source documents: \n",
    "- The name of each source document is at the start of the document, with the <Document tag.\n",
    "        \n",
    "2. Create a report structure using markdown formatting:\n",
    "- Use ## for the section title\n",
    "- Use ### for sub-section headers\n",
    "        \n",
    "3. Write the report following this structure:\n",
    "a. Title (## header)\n",
    "b. Summary (### header)\n",
    "c. Sources (### header)\n",
    "\n",
    "4. Make your title engaging based upon the focus area of the analyst: \n",
    "{focus}\n",
    "\n",
    "5. For the summary section:\n",
    "- Set up summary with general background / context related to the focus area of the analyst\n",
    "- Emphasize what is novel, interesting, or surprising about insights gathered from the interview\n",
    "- Create a numbered list of source documents, as you use them\n",
    "- Do not mention the names of interviewers or experts\n",
    "- Aim for approximately 400 words maximum\n",
    "- Use numbered sources in your report (e.g., [1], [2]) based on information from source documents\n",
    "        \n",
    "6. In the Sources section:\n",
    "- Include all sources used in your report\n",
    "- Provide full links to relevant websites or specific document paths\n",
    "- Separate each source by a newline. Use two spaces at the end of each line to create a newline in Markdown.\n",
    "- It will look like:\n",
    "\n",
    "### Sources\n",
    "[1] Link or Document name\n",
    "[2] Link or Document name\n",
    "\n",
    "7. Be sure to combine sources. For example this is not correct:\n",
    "\n",
    "[3] https://ai.meta.com/blog/meta-llama-3-1/\n",
    "[4] https://ai.meta.com/blog/meta-llama-3-1/\n",
    "\n",
    "There should be no redundant sources. It should simply be:\n",
    "\n",
    "[3] https://ai.meta.com/blog/meta-llama-3-1/\n",
    "        \n",
    "8. Final review:\n",
    "- Ensure the report follows the required structure\n",
    "- Include no preamble before the title of the report\n",
    "- Check that all guidelines have been followed\"\"\"\n",
    "\n",
    "def write_section(state: InterviewState):\n",
    "\n",
    "    \"\"\" Node to answer a question \"\"\"\n",
    "\n",
    "    # Get state\n",
    "    interview = state[\"interview\"]\n",
    "    context = state[\"context\"]\n",
    "    analyst = state[\"analyst\"]\n",
    "   \n",
    "    # Write section using either the gathered source docs from interview (context) or the interview itself (interview)\n",
    "    system_message = section_writer_instructions.format(focus=analyst.description)\n",
    "    section = llm.invoke([SystemMessage(content=system_message)]+[HumanMessage(content=f\"Use this source to write your section: {context}\")]) \n",
    "                \n",
    "    # Append it to state\n",
    "    return {\"sections\": [section.content]}\n",
    "\n",
    "# Add nodes and edges \n",
    "interview_builder = StateGraph(InterviewState)\n",
    "interview_builder.add_node(\"ask_question\", generate_question)\n",
    "interview_builder.add_node(\"search_web\", search_web)\n",
    "interview_builder.add_node(\"search_wikipedia\", search_wikipedia)\n",
    "interview_builder.add_node(\"answer_question\", generate_answer)\n",
    "interview_builder.add_node(\"save_interview\", save_interview)\n",
    "interview_builder.add_node(\"write_section\", write_section)\n",
    "\n",
    "# Flow\n",
    "interview_builder.add_edge(START, \"ask_question\")\n",
    "interview_builder.add_edge(\"ask_question\", \"search_web\")\n",
    "interview_builder.add_edge(\"ask_question\", \"search_wikipedia\")\n",
    "interview_builder.add_edge(\"search_web\", \"answer_question\")\n",
    "interview_builder.add_edge(\"search_wikipedia\", \"answer_question\")\n",
    "interview_builder.add_conditional_edges(\"answer_question\", route_messages,['ask_question','save_interview'])\n",
    "interview_builder.add_edge(\"save_interview\", \"write_section\")\n",
    "interview_builder.add_edge(\"write_section\", END)\n",
    "\n",
    "# Interview \n",
    "memory = MemorySaver()\n",
    "interview_graph = interview_builder.compile(checkpointer=memory).with_config(run_name=\"Conduct Interviews\")\n",
    "\n",
    "# View\n",
    "display(Image(interview_graph.get_graph().draw_mermaid_png()))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "id": "50f382f1-6e93-48d0-a44a-1094d26ccb1e",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Analyst(affiliation='Tech Innovators Inc.', name='Dr. Emily Carter', role='Technology Analyst', description='Dr. Carter focuses on evaluating emerging technologies and their potential impact on various industries. She is particularly interested in how LangGraph can streamline processes and improve efficiency in tech-driven companies.')"
      ]
     },
     "execution_count": 19,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Pick one analyst\n",
    "analysts[0]"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3750ac4f-f458-4b2d-8bad-32ce34895758",
   "metadata": {},
   "source": [
    "Here, we run the interview passing an index of the llama3.1 paper, which is related to our topic."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "id": "b2242d4e-8430-4de9-8cf7-3ad2f9a22b28",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/markdown": [
       "## LangGraph: Revolutionizing Agentic Applications in Tech-Driven Industries\n",
       "\n",
       "### Summary\n",
       "\n",
       "In the rapidly evolving landscape of emerging technologies, LangGraph stands out as a transformative tool for building stateful, multi-actor applications with large language models (LLMs). Dr. Carter's focus on evaluating such technologies reveals LangGraph's potential to streamline processes and enhance efficiency in tech-driven companies. This report delves into the core principles and benefits of LangGraph, highlighting its unique features and industry applications.\n",
       "\n",
       "LangGraph, launched in January 2023, is a low-level orchestration framework designed to build agentic applications. It offers unparalleled controllability, allowing developers to define complex workflows involving cycles, which are essential for most agentic architectures [1]. This level of control is crucial for creating sophisticated, customized agentic systems that can adapt to specific business needs [2].\n",
       "\n",
       "One of the most novel aspects of LangGraph is its ability to balance agent control with agency. This balance is achieved through its core principles: cycles, controllability, and persistence. These principles enable the creation of fully customizable agentic workflows, as opposed to rigid, boilerplate solutions [3]. This flexibility is particularly beneficial for developing advanced chatbots and other interactive applications that require nuanced and dynamic interactions [4].\n",
       "\n",
       "LangGraph Studio further enhances the development process by providing an integrated development environment (IDE) tailored for agentic applications. This IDE streamlines the creation, testing, and deployment of agentic workflows, making it easier for developers to harness the full potential of LangGraph [5].\n",
       "\n",
       "The integration of LangGraph with Semantic Web technologies, such as RDF and OWL, offers additional advantages. These technologies enable the encoding of semantics with data, making it machine-readable and facilitating reasoning over heterogeneous data sources [6]. This integration positions LangGraph as a powerful tool for building intelligent systems that can operate across diverse data environments.\n",
       "\n",
       "In summary, LangGraph represents a significant advancement in the development of agentic applications. Its core principles of cycles, controllability, and persistence, combined with the capabilities of LangGraph Studio and Semantic Web integration, make it a valuable asset for tech-driven companies looking to enhance efficiency and streamline processes.\n",
       "\n",
       "### Sources\n",
       "[1] https://github.com/langchain-ai/langgraph/  \n",
       "[2] https://infohub.delltechnologies.com/en-us/l/rethinking-hierarchical-text-classification-insights-from-multi-agent-experiments-with-small-language-models-1/use-of-langgraph-6/  \n",
       "[3] https://langchain-ai.github.io/langgraph/concepts/high_level/  \n",
       "[4] https://www.linkedin.com/pulse/what-langgraph-how-useful-building-llm-based-sarfraz-nawaz-walic/  \n",
       "[5] https://blog.langchain.dev/langgraph-studio-the-first-agent-ide/  \n",
       "[6] https://en.wikipedia.org/wiki/Semantic_Web"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "execution_count": 20,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from IPython.display import Markdown\n",
    "messages = [HumanMessage(f\"So you said you were writing an article on {topic}?\")]\n",
    "thread = {\"configurable\": {\"thread_id\": \"1\"}}\n",
    "interview = interview_graph.invoke({\"analyst\": analysts[0], \"messages\": messages, \"max_num_turns\": 2}, thread)\n",
    "Markdown(interview['sections'][0])"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3b739e87-68bb-4e96-a86a-704e84240a6c",
   "metadata": {},
   "source": [
    "### Parallelze interviews: Map-Reduce\n",
    "\n",
    "We parallelize the interviews via the `Send()` API, a map step.\n",
    "\n",
    "We combine them into the report body in a reduce step.\n",
    "\n",
    "### Finalize\n",
    "\n",
    "We add a final step to write an intro and conclusion to the final report."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "id": "6a0042f9-5b9f-441a-9e8d-7d8189f44140",
   "metadata": {},
   "outputs": [],
   "source": [
    "import operator\n",
    "from typing import List, Annotated\n",
    "from typing_extensions import TypedDict\n",
    "\n",
    "class ResearchGraphState(TypedDict):\n",
    "    topic: str # Research topic\n",
    "    max_analysts: int # Number of analysts\n",
    "    human_analyst_feedback: str # Human feedback\n",
    "    analysts: List[Analyst] # Analyst asking questions\n",
    "    sections: Annotated[list, operator.add] # Send() API key\n",
    "    introduction: str # Introduction for the final report\n",
    "    content: str # Content for the final report\n",
    "    conclusion: str # Conclusion for the final report\n",
    "    final_report: str # Final report"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "id": "c2224592-d2ff-469d-97bd-928809f896d7",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/jpeg": "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",
      "text/plain": [
       "<IPython.core.display.Image object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "from langgraph.constants import Send\n",
    "\n",
    "def initiate_all_interviews(state: ResearchGraphState):\n",
    "    \"\"\" This is the \"map\" step where we run each interview sub-graph using Send API \"\"\"    \n",
    "\n",
    "    # Check if human feedback\n",
    "    human_analyst_feedback=state.get('human_analyst_feedback')\n",
    "    if human_analyst_feedback:\n",
    "        # Return to create_analysts\n",
    "        return \"create_analysts\"\n",
    "\n",
    "    # Otherwise kick off interviews in parallel via Send() API\n",
    "    else:\n",
    "        topic = state[\"topic\"]\n",
    "        return [Send(\"conduct_interview\", {\"analyst\": analyst,\n",
    "                                           \"messages\": [HumanMessage(\n",
    "                                               content=f\"So you said you were writing an article on {topic}?\"\n",
    "                                           )\n",
    "                                                       ]}) for analyst in state[\"analysts\"]]\n",
    "\n",
    "report_writer_instructions = \"\"\"You are a technical writer creating a report on this overall topic: \n",
    "\n",
    "{topic}\n",
    "    \n",
    "You have a team of analysts. Each analyst has done two things: \n",
    "\n",
    "1. They conducted an interview with an expert on a specific sub-topic.\n",
    "2. They write up their finding into a memo.\n",
    "\n",
    "Your task: \n",
    "\n",
    "1. You will be given a collection of memos from your analysts.\n",
    "2. Think carefully about the insights from each memo.\n",
    "3. Consolidate these into a crisp overall summary that ties together the central ideas from all of the memos. \n",
    "4. Summarize the central points in each memo into a cohesive single narrative.\n",
    "\n",
    "To format your report:\n",
    " \n",
    "1. Use markdown formatting. \n",
    "2. Include no pre-amble for the report.\n",
    "3. Use no sub-heading. \n",
    "4. Start your report with a single title header: ## Insights\n",
    "5. Do not mention any analyst names in your report.\n",
    "6. Preserve any citations in the memos, which will be annotated in brackets, for example [1] or [2].\n",
    "7. Create a final, consolidated list of sources and add to a Sources section with the `## Sources` header.\n",
    "8. List your sources in order and do not repeat.\n",
    "\n",
    "[1] Source 1\n",
    "[2] Source 2\n",
    "\n",
    "Here are the memos from your analysts to build your report from: \n",
    "\n",
    "{context}\"\"\"\n",
    "\n",
    "def write_report(state: ResearchGraphState):\n",
    "    # Full set of sections\n",
    "    sections = state[\"sections\"]\n",
    "    topic = state[\"topic\"]\n",
    "\n",
    "    # Concat all sections together\n",
    "    formatted_str_sections = \"\\n\\n\".join([f\"{section}\" for section in sections])\n",
    "    \n",
    "    # Summarize the sections into a final report\n",
    "    system_message = report_writer_instructions.format(topic=topic, context=formatted_str_sections)    \n",
    "    report = llm.invoke([SystemMessage(content=system_message)]+[HumanMessage(content=f\"Write a report based upon these memos.\")]) \n",
    "    return {\"content\": report.content}\n",
    "\n",
    "intro_conclusion_instructions = \"\"\"You are a technical writer finishing a report on {topic}\n",
    "\n",
    "You will be given all of the sections of the report.\n",
    "\n",
    "You job is to write a crisp and compelling introduction or conclusion section.\n",
    "\n",
    "The user will instruct you whether to write the introduction or conclusion.\n",
    "\n",
    "Include no pre-amble for either section.\n",
    "\n",
    "Target around 100 words, crisply previewing (for introduction) or recapping (for conclusion) all of the sections of the report.\n",
    "\n",
    "Use markdown formatting. \n",
    "\n",
    "For your introduction, create a compelling title and use the # header for the title.\n",
    "\n",
    "For your introduction, use ## Introduction as the section header. \n",
    "\n",
    "For your conclusion, use ## Conclusion as the section header.\n",
    "\n",
    "Here are the sections to reflect on for writing: {formatted_str_sections}\"\"\"\n",
    "\n",
    "def write_introduction(state: ResearchGraphState):\n",
    "    # Full set of sections\n",
    "    sections = state[\"sections\"]\n",
    "    topic = state[\"topic\"]\n",
    "\n",
    "    # Concat all sections together\n",
    "    formatted_str_sections = \"\\n\\n\".join([f\"{section}\" for section in sections])\n",
    "    \n",
    "    # Summarize the sections into a final report\n",
    "    \n",
    "    instructions = intro_conclusion_instructions.format(topic=topic, formatted_str_sections=formatted_str_sections)    \n",
    "    intro = llm.invoke([instructions]+[HumanMessage(content=f\"Write the report introduction\")]) \n",
    "    return {\"introduction\": intro.content}\n",
    "\n",
    "def write_conclusion(state: ResearchGraphState):\n",
    "    # Full set of sections\n",
    "    sections = state[\"sections\"]\n",
    "    topic = state[\"topic\"]\n",
    "\n",
    "    # Concat all sections together\n",
    "    formatted_str_sections = \"\\n\\n\".join([f\"{section}\" for section in sections])\n",
    "    \n",
    "    # Summarize the sections into a final report\n",
    "    \n",
    "    instructions = intro_conclusion_instructions.format(topic=topic, formatted_str_sections=formatted_str_sections)    \n",
    "    conclusion = llm.invoke([instructions]+[HumanMessage(content=f\"Write the report conclusion\")]) \n",
    "    return {\"conclusion\": conclusion.content}\n",
    "\n",
    "def finalize_report(state: ResearchGraphState):\n",
    "    \"\"\" The is the \"reduce\" step where we gather all the sections, combine them, and reflect on them to write the intro/conclusion \"\"\"\n",
    "    # Save full final report\n",
    "    content = state[\"content\"]\n",
    "    if content.startswith(\"## Insights\"):\n",
    "        content = content.strip(\"## Insights\")\n",
    "    if \"## Sources\" in content:\n",
    "        try:\n",
    "            content, sources = content.split(\"\\n## Sources\\n\")\n",
    "        except:\n",
    "            sources = None\n",
    "    else:\n",
    "        sources = None\n",
    "\n",
    "    final_report = state[\"introduction\"] + \"\\n\\n---\\n\\n\" + content + \"\\n\\n---\\n\\n\" + state[\"conclusion\"]\n",
    "    if sources is not None:\n",
    "        final_report += \"\\n\\n## Sources\\n\" + sources\n",
    "    return {\"final_report\": final_report}\n",
    "\n",
    "# Add nodes and edges \n",
    "builder = StateGraph(ResearchGraphState)\n",
    "builder.add_node(\"create_analysts\", create_analysts)\n",
    "builder.add_node(\"human_feedback\", human_feedback)\n",
    "builder.add_node(\"conduct_interview\", interview_builder.compile())\n",
    "builder.add_node(\"write_report\",write_report)\n",
    "builder.add_node(\"write_introduction\",write_introduction)\n",
    "builder.add_node(\"write_conclusion\",write_conclusion)\n",
    "builder.add_node(\"finalize_report\",finalize_report)\n",
    "\n",
    "# Logic\n",
    "builder.add_edge(START, \"create_analysts\")\n",
    "builder.add_edge(\"create_analysts\", \"human_feedback\")\n",
    "builder.add_conditional_edges(\"human_feedback\", initiate_all_interviews, [\"create_analysts\", \"conduct_interview\"])\n",
    "builder.add_edge(\"conduct_interview\", \"write_report\")\n",
    "builder.add_edge(\"conduct_interview\", \"write_introduction\")\n",
    "builder.add_edge(\"conduct_interview\", \"write_conclusion\")\n",
    "builder.add_edge([\"write_conclusion\", \"write_report\", \"write_introduction\"], \"finalize_report\")\n",
    "builder.add_edge(\"finalize_report\", END)\n",
    "\n",
    "# Compile\n",
    "memory = MemorySaver()\n",
    "graph = builder.compile(interrupt_before=['human_feedback'], checkpointer=memory)\n",
    "display(Image(graph.get_graph(xray=1).draw_mermaid_png()))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1b64ba9a-2b5e-40e1-a778-0f635aa3f6d0",
   "metadata": {},
   "source": [
    "Let's ask an open-ended question about LangGraph."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "id": "362932ee-4106-4a2d-a32d-b812eafcf9df",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Name: Dr. Emily Carter\n",
      "Affiliation: Tech Innovators Inc.\n",
      "Role: Technical Analyst\n",
      "Description: Dr. Carter focuses on the technical advantages and innovations brought by adopting LangGraph. She is particularly interested in how LangGraph can improve system efficiency, scalability, and integration with existing technologies.\n",
      "--------------------------------------------------\n",
      "Name: Michael Thompson\n",
      "Affiliation: Business Insights Group\n",
      "Role: Business Strategist\n",
      "Description: Michael Thompson analyzes the business benefits of adopting LangGraph. His focus is on cost reduction, return on investment, and competitive advantage. He evaluates how LangGraph can drive business growth and operational efficiency.\n",
      "--------------------------------------------------\n",
      "Name: Samantha Lee\n",
      "Affiliation: User Experience Research Lab\n",
      "Role: User Experience Analyst\n",
      "Description: Samantha Lee examines the user experience improvements that LangGraph can offer. She is concerned with usability, user satisfaction, and the overall impact on end-users. Her analysis includes how LangGraph can enhance user interaction and engagement.\n",
      "--------------------------------------------------\n"
     ]
    }
   ],
   "source": [
    "# Inputs\n",
    "max_analysts = 3 \n",
    "topic = \"The benefits of adopting LangGraph as an agent framework\"\n",
    "thread = {\"configurable\": {\"thread_id\": \"1\"}}\n",
    "\n",
    "# Run the graph until the first interruption\n",
    "for event in graph.stream({\"topic\":topic,\n",
    "                           \"max_analysts\":max_analysts}, \n",
    "                          thread, \n",
    "                          stream_mode=\"values\"):\n",
    "    \n",
    "    analysts = event.get('analysts', '')\n",
    "    if analysts:\n",
    "        for analyst in analysts:\n",
    "            print(f\"Name: {analyst.name}\")\n",
    "            print(f\"Affiliation: {analyst.affiliation}\")\n",
    "            print(f\"Role: {analyst.role}\")\n",
    "            print(f\"Description: {analyst.description}\")\n",
    "            print(\"-\" * 50)  "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "id": "ac521a5f-5a4f-44f9-8af9-d05228e20882",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'configurable': {'thread_id': '1',\n",
       "  'checkpoint_ns': '',\n",
       "  'checkpoint_id': '1ef6a4b4-a84a-6080-8002-b8c1432e2743'}}"
      ]
     },
     "execution_count": 26,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# We now update the state as if we are the human_feedback node\n",
    "graph.update_state(thread, {\"human_analyst_feedback\": \n",
    "                                \"Add in the CEO of gen ai native startup\"}, as_node=\"human_feedback\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "id": "a3be311f-62ee-49e7-b037-75c53d8960a8",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Name: Dr. Emily Carter\n",
      "Affiliation: Tech Innovators Inc.\n",
      "Role: Technical Analyst\n",
      "Description: Dr. Carter focuses on the technical advantages and innovations brought by adopting LangGraph. She is particularly interested in how LangGraph can improve system efficiency, scalability, and integration with existing technologies.\n",
      "--------------------------------------------------\n",
      "Name: Michael Thompson\n",
      "Affiliation: Business Insights Group\n",
      "Role: Business Strategist\n",
      "Description: Michael Thompson analyzes the business benefits of adopting LangGraph. His focus is on cost reduction, return on investment, and competitive advantage. He evaluates how LangGraph can drive business growth and operational efficiency.\n",
      "--------------------------------------------------\n",
      "Name: Samantha Lee\n",
      "Affiliation: User Experience Research Lab\n",
      "Role: User Experience Analyst\n",
      "Description: Samantha Lee examines the user experience improvements that LangGraph can offer. She is concerned with usability, user satisfaction, and the overall impact on end-users. Her analysis includes how LangGraph can enhance user interaction and engagement.\n",
      "--------------------------------------------------\n",
      "Name: Dr. Emily Carter\n",
      "Affiliation: Tech Innovators Inc.\n",
      "Role: Technology Adoption Specialist\n",
      "Description: Dr. Carter focuses on the strategic benefits and challenges of adopting new technologies in business environments. She is particularly interested in how LangGraph can streamline operations and improve efficiency.\n",
      "--------------------------------------------------\n",
      "Name: Alex Martinez\n",
      "Affiliation: GenAI Solutions\n",
      "Role: CEO\n",
      "Description: Alex Martinez is the CEO of a generative AI native startup. His primary concern is how LangGraph can enhance the capabilities of generative AI models, improve scalability, and provide a competitive edge in the market.\n",
      "--------------------------------------------------\n",
      "Name: Priya Singh\n",
      "Affiliation: Data Security Insights\n",
      "Role: Data Security Analyst\n",
      "Description: Priya Singh specializes in data security and privacy issues. She evaluates how adopting LangGraph can impact data security protocols, compliance with regulations, and overall data integrity.\n",
      "--------------------------------------------------\n"
     ]
    }
   ],
   "source": [
    "# Check\n",
    "for event in graph.stream(None, thread, stream_mode=\"values\"):\n",
    "    analysts = event.get('analysts', '')\n",
    "    if analysts:\n",
    "        for analyst in analysts:\n",
    "            print(f\"Name: {analyst.name}\")\n",
    "            print(f\"Affiliation: {analyst.affiliation}\")\n",
    "            print(f\"Role: {analyst.role}\")\n",
    "            print(f\"Description: {analyst.description}\")\n",
    "            print(\"-\" * 50)  "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "id": "0af41f54-88d9-4597-98b0-444c08322095",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'configurable': {'thread_id': '1',\n",
       "  'checkpoint_ns': '',\n",
       "  'checkpoint_id': '1ef6a4b5-4229-61e2-8004-d32a00c0326b'}}"
      ]
     },
     "execution_count": 28,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Confirm we are happy\n",
    "graph.update_state(thread, {\"human_analyst_feedback\": \n",
    "                            None}, as_node=\"human_feedback\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "id": "37123ca7-c20b-43c1-9a71-39ba344e7ca6",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "--Node--\n",
      "conduct_interview\n",
      "--Node--\n",
      "conduct_interview\n",
      "--Node--\n",
      "conduct_interview\n",
      "--Node--\n",
      "write_introduction\n",
      "--Node--\n",
      "write_conclusion\n",
      "--Node--\n",
      "write_report\n",
      "--Node--\n",
      "finalize_report\n"
     ]
    }
   ],
   "source": [
    "# Continue\n",
    "for event in graph.stream(None, thread, stream_mode=\"updates\"):\n",
    "    print(\"--Node--\")\n",
    "    node_name = next(iter(event.keys()))\n",
    "    print(node_name)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "id": "f8f66ad8-80fd-4eb2-96b6-6ae9dffd060c",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/markdown": [
       "# The Benefits of Adopting LangGraph as an Agent Framework\n",
       "\n",
       "## Introduction\n",
       "\n",
       "In the rapidly evolving landscape of artificial intelligence, businesses are increasingly seeking advanced technologies to streamline operations and enhance efficiency. LangGraph, a robust framework for building stateful, multi-actor applications with large language models (LLMs), stands out as a transformative tool. This report delves into the strategic business efficiencies offered by LangGraph, its role in enhancing generative AI models for scalability and market competitiveness, and its impact on data security and privacy. By exploring these facets, we aim to highlight how LangGraph can be a game-changer for businesses looking to leverage AI for complex task automation and operational excellence.\n",
       "\n",
       "---\n",
       "\n",
       "\n",
       "\n",
       "In the rapidly evolving landscape of artificial intelligence, businesses are increasingly adopting advanced technologies to streamline operations, enhance efficiency, and maintain robust data security. LangGraph, a robust framework for building stateful, multi-actor applications with large language models (LLMs), stands out as a transformative tool for these purposes. This report consolidates insights from various analyses to highlight the strategic benefits of adopting LangGraph as an agent framework.\n",
       "\n",
       "LangGraph excels in handling complex, bespoke tasks essential for modern business operations. Unlike simpler frameworks, LangGraph is adept at creating and managing sophisticated workflows involving multiple AI agents, making it particularly beneficial for businesses looking to automate complex processes and improve operational efficiency.\n",
       "\n",
       "Key insights from the analysis of LangGraph include:\n",
       "\n",
       "1. **Stateful Multi-Actor Applications**: LangGraph's ability to build stateful applications allows for the creation of dynamic and adaptive workflows. This is crucial for businesses that require real-time adjustments based on evolving data and task requirements [1][2].\n",
       "\n",
       "2. **Cycles, Controllability, and Persistence**: These core benefits of LangGraph enable businesses to define cyclical processes, maintain control over AI agent actions, and ensure the persistence of data and states across sessions. This leads to more reliable and consistent performance of AI-driven operations [2][3].\n",
       "\n",
       "3. **Integration and Scalability**: LangGraph's framework supports the integration of diverse AI agent types within a unified system, facilitating the development of scalable solutions. This is particularly advantageous for businesses aiming to expand their AI capabilities without overhauling existing systems [4][5].\n",
       "\n",
       "4. **Enhanced Performance Evaluation**: By providing tools to evaluate and optimize AI performance, LangGraph helps businesses ensure that their AI solutions are not only effective but also efficient. This is critical for maintaining competitive advantage in a technology-driven market [1][5].\n",
       "\n",
       "5. **Custom LLM-Backed Experiences**: LangGraph enables the creation of custom experiences powered by LLMs, which can be tailored to specific business needs. This customization potential allows businesses to develop unique solutions that address their particular challenges and opportunities [1][4].\n",
       "\n",
       "LangGraph also enhances the capabilities of generative AI models, improving scalability and providing a competitive edge in the market. By facilitating the creation of cyclic graphs for LLM-based AI agents, LangGraph allows for more variable and nuanced agent behaviors compared to traditional linear execution models [1]. This approach bridges the gap between the potential of LLMs and the requirements of real-world software development, making it a valuable tool for startups and established businesses alike.\n",
       "\n",
       "Key insights from this perspective include:\n",
       "\n",
       "1. **Framework for Controlled AI Applications**: LangGraph provides a structured framework for creating controlled, production-ready AI applications, which is essential for meeting the stringent requirements of real-world software development [1].\n",
       "\n",
       "2. **Cyclic Graph Topologies**: By viewing agent workflows as cyclic graph topologies, LangGraph enables more nuanced and variable agent behaviors, enhancing the flexibility and adaptability of AI models [2].\n",
       "\n",
       "3. **Integration with LangChain**: LangGraph is built on top of LangChain, leveraging its capabilities to create more efficient and stateful multi-actor applications. This integration allows for better coordination and checkpointing of different chains or actors using regular Python functions [4].\n",
       "\n",
       "4. **Real-World Applications**: LangGraph has been successfully applied in complex data analysis scenarios, demonstrating its practical utility and effectiveness in handling diverse AI agent types within a unified framework [5].\n",
       "\n",
       "5. **Improving Retrieval-Augmented Generation (RAG)**: LangGraph, in conjunction with LangChain, can significantly improve RAG by creating more efficient and conditional workflows, which are essential for generating accurate and contextually relevant responses [6].\n",
       "\n",
       "In the context of data security and privacy, LangGraph offers a structured framework for defining, coordinating, and executing multiple LLM agents, which can significantly streamline the development of complex AI applications. One of its key features is the ability to create cyclical graphs, essential for developing stateful, multi-actor applications [1]. This capability can enhance the efficiency and reliability of AI-driven processes, which is critical for maintaining data integrity.\n",
       "\n",
       "However, LangGraph does not enforce best practices as rigorously as some other tools. This flexibility can lead to suboptimal results if developers do not adhere to established security protocols [2]. Despite this, LangGraph's higher level of control can be advantageous for developers who are well-versed in data security practices.\n",
       "\n",
       "The recent release of LangGraph v0.2 introduces new checkpointer libraries, including a SQLite checkpointer for local workflows and an optimized Postgres checkpointer for production environments [3]. These enhancements provide increased customization options, which can be leveraged to improve data security measures. Additionally, the introduction of LangGraph Cloud offers new opportunities for scalable and secure AI application development.\n",
       "\n",
       "In summary, LangGraph offers a comprehensive solution for businesses looking to leverage AI for complex task automation, operational efficiency, and data security. Its unique features and strategic advantages make it a valuable tool for businesses aiming to stay ahead in a competitive market.\n",
       "\n",
       "\n",
       "---\n",
       "\n",
       "## Conclusion\n",
       "\n",
       "LangGraph emerges as a transformative framework for businesses aiming to leverage AI for enhanced operational efficiency, scalability, and data security. By enabling the creation of stateful, multi-actor applications, LangGraph addresses the complex needs of modern enterprises. Its unique features, such as cycles, controllability, and persistence, offer significant advantages in automating intricate workflows. The integration and scalability capabilities further ensure that businesses can expand their AI solutions seamlessly. Additionally, LangGraph's tools for performance evaluation and custom LLM-backed experiences provide a competitive edge in the market. Despite some challenges in enforcing best practices, LangGraph's advanced features and recent updates make it a valuable asset for businesses focused on strategic efficiency, generative AI model enhancement, and robust data security.\n",
       "\n",
       "## Sources\n",
       "[1] https://www.langchain.com/langgraph  \n",
       "[2] https://github.com/langchain-ai/langgraph  \n",
       "[3] https://medium.com/@ga3435/ai-agentic-frameworks-2022fe43e78a  \n",
       "[4] https://www.datacamp.com/tutorial/langgraph-tutorial  \n",
       "[5] https://github.com/langchain-ai/langgraph/discussions/1093  \n",
       "[6] https://medium.com/data-science-in-your-pocket/improving-rag-using-langgraph-and-langchain-bb195bfe4b44  \n",
       "[7] https://opendatascience.com/langgraph-the-future-of-production-ready-ai-agents/  \n",
       "[8] https://www.analyticsvidhya.com/blog/2024/07/langgraph-revolutionizing-ai-agent/  \n",
       "[9] https://towardsdatascience.com/how-to-implement-a-genai-agent-using-autogen-or-langgraph-929135afd34d  \n",
       "[10] https://adasci.org/a-practical-guide-to-building-ai-agents-with-langgraph/  \n",
       "[11] https://towardsdatascience.com/from-basics-to-advanced-exploring-langgraph-e8c1cf4db787  \n",
       "[12] https://blog.langchain.dev/langgraph-v0-2/"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "execution_count": 30,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from IPython.display import Markdown\n",
    "final_state = graph.get_state(thread)\n",
    "report = final_state.values.get('final_report')\n",
    "Markdown(report)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e9bf8edd-fb42-496c-9bdb-3f5d7b4d79d3",
   "metadata": {},
   "source": [
    "We can look at the trace:\n",
    "\n",
    "https://smith.langchain.com/public/2933a7bb-bcef-4d2d-9b85-cc735b22ca0c/r"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "808bd094",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.11.8"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
